package com.hs.android.fortress.ingame;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.util.EntityUtils;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.hs.android.fortress.model.ExplosionInformation;
import com.hs.android.fortress.model.Player;
import com.hs.android.fortress.net.GetMethodCommand;
import com.hs.android.fortress.net.NetworkCommand;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;

public class GameInformationGetter extends HandlerThread {

	private static final String TAG = "PositionsGetter";
	private static final int INFORMATION_GET = 0;

	private static final String GET_INFORMATION_URL = "/gamecontroller/game?number=";

	Handler mHandler;
	Handler mResponseHandler;
	Listener mListener;
	NetworkCommand mCommand;

	public interface Listener {
		void onPositionsGotten(List<Player> players);
		void onExposionGotten(List<ExplosionInformation> explosionInformations);
	}

	public void setListener(Listener listener) {
		mListener = listener;
	}

	public GameInformationGetter(Handler responseHandler) {
		super(TAG);
		mResponseHandler = responseHandler;
	}

	@Override
	protected void onLooperPrepared() {
		mHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				if (msg.what == INFORMATION_GET) {
					int roomNumber = (Integer) msg.obj;
					handleRequest(roomNumber);
				}
			}
		};
	}

	public void queueRoomNumber(int roomNumber) {
		mHandler.obtainMessage(INFORMATION_GET, roomNumber).sendToTarget();
	}

	private void handleRequest(int roomNumber) {

		String result = null;

		mCommand = new GetMethodCommand(GET_INFORMATION_URL + roomNumber);

		try {
			HttpResponse response = mCommand.callMethod();

			// status 200 means "OK" - the request has succeeded
			if (response.getStatusLine().getStatusCode() != 200) {
				Log.d(TAG, "Status: "
						+ response.getStatusLine().getStatusCode());
				return;
			}

			HttpEntity entity = response.getEntity();
			result = EntityUtils.toString(entity);

			if (result != null) {
				Gson gson = new Gson();
				
				Type mapType = new TypeToken<HashMap<String, String>>(){}.getType();
				Map<String,String> gameInfoMap = gson.fromJson(result, mapType);
				
				String playersStr = gameInfoMap.get("players");
				String explosionStr = gameInfoMap.get("explosion");
				
				List<Player> players = null;
				if(playersStr != null){
					Type poslistType = new TypeToken<ArrayList<Player>>(){}.getType();
					players = gson.fromJson(playersStr, poslistType);
				}
				
				List<ExplosionInformation> explosionInformations =null;
				if(explosionStr != null){
					Type exlistType = new TypeToken<ArrayList<ExplosionInformation>>() {}.getType();
					explosionInformations = gson.fromJson(explosionStr, exlistType);
				}
				
				mResponseHandler.post(new handlerPost(players, explosionInformations));
			}

		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public void clearQueue() {
		mHandler.removeMessages(INFORMATION_GET);
	}
	
	private class handlerPost implements Runnable{

		private List<Player> players;
		private List<ExplosionInformation> explosionInformations;
		
		handlerPost(List<Player> positions, List<ExplosionInformation> explosionInformations) {
			this.players = positions;
			this.explosionInformations = explosionInformations;
		}
		
		@Override
		public void run() {
			
			if(players != null){
				if(mListener != null)
					mListener.onPositionsGotten(players);
			}
				
			if(explosionInformations !=null){
				if(mListener != null)
					mListener.onExposionGotten(explosionInformations);
			}
			
		}
	}
}
